package com.edu.service.impl;

import com.edu.mapper.ExciseMapper;
import com.edu.pojo.Excise;
import com.edu.pojo.AllKeyEnum;
import com.edu.service.ExciseService;
import com.edu.util.JsonUtil;
import com.edu.util.RedisClientUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * @author five-five
 * @created 2021/11/12 - 12:19
 */
@Service
public class ExciseServiceImpl implements ExciseService {
    @Resource
    private ExciseMapper exciseMapper;
    @Resource
    private RedisClientUtil redisClientUtil;

    @Override
    public Excise[][] generateAddFormulaBase(HttpServletRequest request) {
        int[][] nums = new int[101][101];
        Excise[][] excises = new Excise[nums.length][nums[1].length];
        //如果会话命中
        String data = (String) request.getSession().getAttribute(AllKeyEnum.ADD_BASES.getKey());
        if (StringUtils.isNotBlank(data)) {
            List<Excise[]> list = JsonUtil.jsonToList(data, Excise[].class);
            int size = list.size();
            excises = new Excise[size][size];
            for (int i = 0; i < size; i++) {
                excises[i] = list.get(i);
            }
            return excises;
        }
        //如果缓存命中
        String add_base = null;
        try {
            add_base = redisClientUtil.get(AllKeyEnum.ADD_BASES.getKey());
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (StringUtils.isNotBlank(add_base)) {
            List<Excise[]> list = null;
            try {
                list = JsonUtil.jsonToList(add_base, Excise[].class);
            } catch (Exception e) {
                e.printStackTrace();
            }
            for (int i = 0; i < Objects.requireNonNull(list).size(); i++) {
                excises[i] = list.get(i);
            }
            return excises;
        }
        for (int i = 0; i < nums.length; i++) {
            for (int j = 0; j < nums[i].length; j++) {
                Excise excise = new Excise();
                excise.setLeft((j + ""));
                excise.setRight((i + ""));
                excise.setSymbol("+");
                excise.setResult((i + j) + "");
                excises[i][j] = excise;
            }
        }
        redisClientUtil.set(AllKeyEnum.ADD_BASES.getKey(), JsonUtil.objectToJson(excises));
        redisClientUtil.expire(AllKeyEnum.ADD_BASES.getKey(), 3000 * 10);
        return excises;
    }

    @Override
    public Excise[][] generateSubtractFormulaBase(HttpServletRequest request) {
        int[][] nums = new int[101][101];
        Excise[][] excises = new Excise[nums.length][nums[1].length];
        //如果会话命中
        String data = (String) request.getSession().getAttribute(AllKeyEnum.SUBTRACT_BASES.getKey());
        if (StringUtils.isNotBlank(data)) {
            List<Excise[]> list = JsonUtil.jsonToList(data, Excise[].class);
            int size = list.size();
            excises = new Excise[size][size];
            for (int i = 0; i < size; i++) {
                excises[i] = list.get(i);
            }
            return excises;
        }
        //如果缓存命中
        String subtract_base = null;
        try {
            subtract_base = redisClientUtil.get(AllKeyEnum.SUBTRACT_BASES.getKey());
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (StringUtils.isNotBlank(subtract_base)) {
            List<Excise[]> list = null;
            try {
                list = JsonUtil.jsonToList(subtract_base, Excise[].class);
            } catch (Exception e) {
                e.printStackTrace();
            }
            for (int i = 0; i < Objects.requireNonNull(list).size(); i++) {
                excises[i] = list.get(i);
            }
            return excises;
        }
        for (int i = 0; i < nums.length; i++) {
            for (int j = 0; j < nums[i].length; j++) {
                Excise excise = new Excise();
                excise.setLeft((j + ""));
                excise.setRight((i + ""));
                excise.setSymbol("-");
                excise.setResult((j - i) + "");
                excises[i][j] = excise;
            }
        }
        try {
            redisClientUtil.set(AllKeyEnum.SUBTRACT_BASES.getKey(), JsonUtil.objectToJson(excises));
            redisClientUtil.expire(AllKeyEnum.SUBTRACT_BASES.getKey(), 3000 * 10);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return excises;
    }

    @Override
    public List<Excise> generateAddExcises(int length, HttpServletRequest request) {
        Excise[][] excises = generateAddFormulaBase(request);

        List<Excise> exciseList = new ArrayList<>();
        while (exciseList.size() < length) {
            int x = (int) Math.ceil(Math.random() * excises.length)-1;
            int y = (int) Math.ceil(Math.random() * excises.length)-1;
            Excise excise = excises[x][y];
            if (Integer.parseInt(excise.getResult()) > 0
                    && Integer.parseInt(excise.getResult()) < 100
                    && !exciseList.contains(excise)) {
                exciseList.add(excise);
            }
        }
        return exciseList;
    }

    @Override
    public List<Excise> generateSubtractExcises(int length, HttpServletRequest request) {
        Excise[][] excises = generateSubtractFormulaBase(request);
        List<Excise> exciseList = new ArrayList<>();
        while (exciseList.size() < length) {
            int x = (int) Math.ceil(Math.random() * excises.length)-1;
            int y = (int) Math.ceil(Math.random() * excises.length)-1;
            Excise excise = excises[x][y];
            if (Integer.parseInt(excise.getResult()) > 0
                    && Integer.parseInt(excise.getResult()) < 100
                    && !exciseList.contains(excise)) {
                exciseList.add(excise);
            }
        }
        return exciseList;
    }

    @Override
    public Map<String, List<Excise>> randomGenerateSubtractExcises(int maxlength, int length, HttpServletRequest request) {
        Map<String, List<Excise>> map = new LinkedHashMap<>();
        List<Excise> addExcises = generateAddExcises(length, request);
        List<Excise> subtractExcises = generateSubtractExcises(maxlength - length, request);
        map.put(AllKeyEnum.ADD_ADDEXCISES.getKey(), addExcises);
        map.put(AllKeyEnum.SUBTRACT_SUBTRACTEXCISES.getKey(),  subtractExcises);
        return map;
    }

}
